package br.com.kaetec.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import br.com.kaetec.entities.Cliente;
import br.com.kaetec.entities.Contato;
import br.com.kaetec.entities.SexoType;
import br.com.kaetec.utils.LogDeProcessamento;

public class ClienteDAO {

	public static String TABLE = "clientes";
	
	public boolean adiciona(Cliente cliente) {
		
		boolean insertOk = false;
		String sql  =	"INSERT INTO " + TABLE + "(" +
						"NOME" +
						",RG" +
						",CPF" +
						",SEXO" +
						")"+
						" VALUES (?,?,?,?)";
		
		ConnectionFactory con = new ConnectionFactory( "BD_MYSQL" );
		PreparedStatement stmt = null;
		ResultSet rs = null;
		
		try {
			
			con.beginTransaction();
			
			//-----------------------------------------------------------------------
			//- Prepara instrucao sql de Insert para retornar o ID gerado no Insert -
			//-----------------------------------------------------------------------
			stmt = con.getPrepareStatementFromSQL(sql, true);
			
			int index = 0;
			stmt.setString(++index, cliente.getNome());
			stmt.setString(++index, cliente.getRg());
			stmt.setString(++index, cliente.getCpf());
			stmt.setString(++index, cliente.getSexo().toString());
	        
			stmt.executeUpdate();
			
			if ( cliente.getContato() != null ) {
			
				//--------------------------------
				//- Recupera ID gerado no Insert -
				//--------------------------------
				rs = stmt.getGeneratedKeys();
				
				//---------------------------------------------
				//- Atribui o ID recuperado ao objeto cliente -
				//---------------------------------------------
				if ( rs.next() ) {
					cliente.setId( rs.getLong(1) );
				}
	    
		        ContatoDAO contato = new ContatoDAO();
		        contato.mantemContato(cliente);
		        
			}
                        
                        con.endTransaction(null, stmt, null);
		        insertOk = true;
	        
			LogDeProcessamento.gravaLog(null,"INSERT: executado com sucesso.");
	        
		}
		catch (SQLException e) {  
          
			LogDeProcessamento.gravaLog(null,"INSERT: " + sql + " com erro!");			
			LogDeProcessamento.gravaLog(null, e.getMessage());
	        
		} 
		catch (Exception e) {  
          
			LogDeProcessamento.gravaLog(null,"INSERT: " + sql + " com erro!");			
			LogDeProcessamento.gravaLog(null, e.getMessage());
		}
		finally{
		
			con.fecharConexao(null, stmt, null);
			LogDeProcessamento.gravaLog(null, "INSERT: Conexoes fechadas.");
			
		}
		
		return insertOk;
		
	}
	
	public boolean atualiza(Cliente cliente) {
		
		boolean updateOk = false;
		String sql =	"UPDATE " + TABLE + " SET " +
						"NOME = ?," +
						"RG = ?," +
						"CPF = ?," +
						"SEXO = ?," +				
						" WHERE ID = ?";
		
		ConnectionFactory con = new ConnectionFactory( "BD_MYSQL" );
		PreparedStatement stmt = null;
				
		try {
			
			con.beginTransaction();
			
			stmt = con.getPrepareStatementFromSQL(sql, false);
			
			int index = 0;
			stmt.setString(++index, cliente.getNome());
			stmt.setString(++index, cliente.getRg());
			stmt.setString(++index, cliente.getCpf());
			stmt.setString(++index, cliente.getSexo().toString());
			stmt.setLong(++index, cliente.getId());
			
			stmt.executeUpdate();
			
			con.endTransaction(null, stmt, null);
	        updateOk = true;
	        
	        LogDeProcessamento.gravaLog(null,"UPDATE: executado com sucesso.");
	        
		}
		catch (SQLException e) {  
          
			LogDeProcessamento.gravaLog(null,"UPDATE: " + sql + " com erro!");
			LogDeProcessamento.gravaLog(null, e.getMessage());
	        
		} 
		catch (Exception e) {  
          
			LogDeProcessamento.gravaLog(null,"UPDATE: " + sql + " com erro!");
			LogDeProcessamento.gravaLog(null, e.getMessage());
			
		}
		finally{
			
			con.fecharConexao(null, stmt, null);
			LogDeProcessamento.gravaLog(null, "UPDATE: Conex�es fechadas.");
			
		}
		
		return updateOk;
		
	}
	
	public boolean exclui(Cliente cliente) {
		
		boolean deleteOk = false;		
		String sql  =	"UPDATE " + TABLE + " SET " +
						"DEL = '*' " +
						" WHERE ID = ?";
		
		ConnectionFactory con = new ConnectionFactory( "BD_MYSQL" );
		PreparedStatement stmt = null;
		
		try {
			
			con.beginTransaction();
			stmt = con.getPrepareStatementFromSQL(sql, false);
			
			stmt.setLong(1, cliente.getId());
			stmt.executeUpdate();  
			
			con.endTransaction(null, stmt, null);
			deleteOk = true;
	        
	        LogDeProcessamento.gravaLog(null,"DELETE: executado com sucesso.");
	        
		}
		catch (SQLException e) {  
          
			LogDeProcessamento.gravaLog(null,"DELETE: " + sql + " com erro!");
			LogDeProcessamento.gravaLog(null, e.getMessage());
	        
		} 
		catch (Exception e) {  
          
			LogDeProcessamento.gravaLog(null,"DELETE: " + sql + " com erro!");
			LogDeProcessamento.gravaLog(null, e.getMessage());
		}
		finally{
			
			con.fecharConexao(null, stmt, null);
			LogDeProcessamento.gravaLog(null, "DELETE: Conex�es fechadas.");
			
		}
		
		return deleteOk;
		
	}
	
	public Cliente getClienteFromNome( String nome ) throws SQLException{
		
		Cliente cliente = new Cliente();
		String sql = "";
		ConnectionFactory con = new ConnectionFactory( "BD_MYSQL" );
		PreparedStatement stmtClientes = null;
		ResultSet rs = null;
				
		try {
		
			con.beginTransaction();
			sql = "SELECT * FROM " + TABLE + " WHERE DEL = ' ' AND NOME = ?";
			stmtClientes = con.getPrepareStatementFromSQL(sql, false);
		
			stmtClientes.setString(1, nome);
			rs = stmtClientes.executeQuery();
			
			if ( rs.next() ) {

				//---------------------------
				//- Popula o objeto cliente -
				//---------------------------
				cliente = getClienteFromResultSet( rs );
			
			}
			
			con.endTransaction(null,stmtClientes,rs);
		}
		catch (SQLException e) {  
		          
				LogDeProcessamento.gravaLog(null,"getClienteFromNome: " + sql + " com erro!");
				LogDeProcessamento.gravaLog(null, e.getMessage());
		        
		} 
		catch (Exception e) {  
          
			LogDeProcessamento.gravaLog(null,"getClienteFromNome: " + sql + " com erro!");
			LogDeProcessamento.gravaLog(null, e.getMessage());
		}
		
		finally{
			con.fecharConexao(null, stmtClientes, rs);
		}
			
		return cliente;
	}
		
	private Cliente getClienteFromResultSet( ResultSet rs ) throws SQLException {
		
		Cliente cliente = new Cliente();
		
		//---------------------------
		//- Popula o objeto cliente -
		//---------------------------
		cliente.setId(rs.getLong("ID"));
		cliente.setNome(rs.getString("NOME"));
		cliente.setRg(rs.getString("RG"));
		cliente.setCpf(rs.getString("CPF"));
		
		//-----------------------------------------------
		//- Tratamento de dados do Enum Sexo do cliente -
		//-----------------------------------------------
		switch ( rs.getString("SEXO") ) {
			
			case "M":
				cliente.setSexo(SexoType.M);
				break;
				
			case "F":
				cliente.setSexo(SexoType.F);
				break;

			default:
				break;
		}
		
		ArrayList<Contato> contatos = new ArrayList<Contato>();
		contatos = ContatoDAO.getContatosFromClienteId(cliente);
		cliente.setContato(contatos);
		
		return cliente;
	}
	
	public List<Cliente> getLista() {
		
		try {
			
			ConnectionFactory con = new ConnectionFactory( "BD_MYSQL" );
			Connection connection = con.criarConexao();
			PreparedStatement stmtClientes = connection.prepareStatement("SELECT * FROM " + TABLE + " WHERE DEL = ' '");

			List<Cliente> clientes = new ArrayList<Cliente>();
			ResultSet rs = stmtClientes.executeQuery();

			while(rs.next()) {
			
				Cliente cliente = new Cliente();
				cliente = getClienteFromResultSet( rs );
				
				//-------------------------------
				//- Adiciona o cliente na lista -
				//-------------------------------
				clientes.add(cliente);
			}

			rs.close();
			stmtClientes.close();

			return clientes;
			
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

    public boolean excluiForId(long idCliente) {
        
        boolean deleteOk = false;		
        String sql  =	"UPDATE " + TABLE + " SET " +
                                        "DEL = '*' " +
                                        " WHERE ID = ?";

        ConnectionFactory con = new ConnectionFactory( "BD_MYSQL" );
        PreparedStatement stmt = null;

        try {

                con.beginTransaction();
                stmt = con.getPrepareStatementFromSQL(sql, false);

                stmt.setLong(1, idCliente);
                stmt.executeUpdate();  

                con.endTransaction(null, stmt, null);
                deleteOk = true;

        LogDeProcessamento.gravaLog(null,"DELETE: executado com sucesso.");

        }
        catch (SQLException e) {  

                LogDeProcessamento.gravaLog(null,"DELETE: " + sql + " com erro!");
                LogDeProcessamento.gravaLog(null, e.getMessage());

        } 
        catch (Exception e) {  

                LogDeProcessamento.gravaLog(null,"DELETE: " + sql + " com erro!");
                LogDeProcessamento.gravaLog(null, e.getMessage());
        }
        finally{

                con.fecharConexao(null, stmt, null);
                LogDeProcessamento.gravaLog(null, "DELETE: Conex�es fechadas.");

        }

        return deleteOk;
    }

    public Cliente getClienteForId(long id) {
        
        Cliente cliente = new Cliente();
        String sql = "";
        ConnectionFactory con = new ConnectionFactory( "BD_MYSQL" );
        PreparedStatement stmtClientes = null;
        ResultSet rs = null;

        try {

            con.beginTransaction();
            sql = "SELECT * FROM " + TABLE + " WHERE DEL = ' ' AND ID = ?";
            stmtClientes = con.getPrepareStatementFromSQL(sql, false);

            stmtClientes.setLong(1, id);
            rs = stmtClientes.executeQuery();

            if ( rs.next() ) {

                    //---------------------------
                    //- Popula o objeto cliente -
                    //---------------------------
                    cliente = getClienteFromResultSet( rs );

            }

            con.endTransaction(null,stmtClientes,rs);
        }
        catch (SQLException e) {  
            LogDeProcessamento.gravaLog(null,"getClienteFromNome: " + sql + " com erro!");
            LogDeProcessamento.gravaLog(null, e.getMessage());
        } 
        catch (Exception e) {  
            LogDeProcessamento.gravaLog(null,"getClienteFromNome: " + sql + " com erro!");
            LogDeProcessamento.gravaLog(null, e.getMessage());
        }

        finally{
            con.fecharConexao(null, stmtClientes, rs);
        }

        return cliente;
        
    }

}